﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using Collab.Modules.ContactBrowser.ViewModel;
using Collab.Services.Remote.WebserviceProxy.ServiceProxy;

namespace Collab.Modules.ContactBrowser.View
{
    /// <summary>
    /// Interaction logic for ContactsView.xaml
    /// </summary>
    public partial class ContactsView : UserControl
    {
        private Point _lastMouseDown;
        private Contact _targetGroup;
        private Contact draggedSource;

        public ContactsView()
        {
            InitializeComponent();
        }

        private void DeleteContact_Click(object sender, RoutedEventArgs e)
        {
            (this.DataContext as ContactsViewModel).DeleteContactCommand.Execute((sender as FrameworkElement).DataContext);
        }

        private void Join_Click(object sender, RoutedEventArgs e)
        {
            (this.DataContext as ContactsViewModel).JoinContactCommand.Execute((sender as FrameworkElement).DataContext);
        }

        private void InviteToSession_Click(object sender, RoutedEventArgs e)
        {
            (this.DataContext as ContactsViewModel).InviteContactCommand.Execute((sender as FrameworkElement).DataContext);
        }

        #region drag and drop

        /// <summary>
        /// Handles the MouseDown event of the GroupTreeView control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void GroupTreeView_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                _lastMouseDown = e.GetPosition(GroupTreeView);
            }
        }

        private void GroupTreeView_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                Point currentPosition = e.GetPosition(GroupTreeView);

                // Note: This should be based on some accessibility number and not just 2 pixels
                if ((Math.Abs(currentPosition.X - _lastMouseDown.X) > 2.0) ||
                    (Math.Abs(currentPosition.Y - _lastMouseDown.Y) > 2.0))
                {
                    Contact selectedItem = (Contact)GroupTreeView.SelectedItem;
                    if ((selectedItem != null))
                    {
                        TreeViewItem container = GetContainerFromContact(selectedItem);
                        if (container != null)
                        {
                            draggedSource = selectedItem;
                            DragDropEffects finalDropEffect = DragDrop.DoDragDrop(container, selectedItem, DragDropEffects.Copy);
                            if ((finalDropEffect == DragDropEffects.Copy) && (_targetGroup != null))
                            {
                                
                            }
                        }
                    }
                }
            }
        }

        private TreeViewItem GetContainerFromContact(Contact selectedItem)
        {
            IEnumerable<Group> groups = ((ObservableCollection<Group>)GroupTreeView.ItemsSource).Where(g => g.Users.Contains(selectedItem));

            //UNDONE: change
            return new TreeViewItem();
        }

        private TreeViewItem GetNearestContainer(UIElement element)
        {
            // Walk up the element tree to the nearest tree view item.
            TreeViewItem container = element as TreeViewItem;
            while ((container == null) && (element != null))
            {
                element = VisualTreeHelper.GetParent(element) as UIElement;
                container = element as TreeViewItem;
            }

            return container;
        }

        private void GroupTreeView_Drop(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.None;
            e.Handled = true;


            // Verify that this is a valid drop and then store the drop target
            //TODO: remove draggedSource - not needed!
            TreeViewItem container = GetNearestContainer(e.OriginalSource as UIElement);
            if (container != null && draggedSource != null)
            {
                Group group = (Group)container.Header;
                if (!group.Users.Contains(draggedSource))
                {
                    (this.DataContext as ContactsViewModel).GroupDroppedTo = group;
                    (this.DataContext as ContactsViewModel).InviteToGroupCommand.Execute((sender as TreeView).SelectedItem);
                    e.Effects = DragDropEffects.Copy;
                }
            }

            draggedSource = null;
        }

        private void GroupTreeView_CheckDropTarget(object sender, DragEventArgs e)
        {
            TreeViewItem container;
            if (!IsValidDropTarget(e.OriginalSource as UIElement, out container))
            {
                e.Effects = DragDropEffects.None;
            }
            else
            {
                container.Background = new SolidColorBrush(Colors.Aquamarine);
            }
            e.Handled = true;
            

        }

        private bool IsValidDropTarget(UIElement target, out TreeViewItem item)
        {
            item = null;
            if (target != null)
            {
                TreeViewItem container = GetNearestContainer(target);
                item = container;

                // Ensure that the target is one of the root items
                // UNDONE: check the group name not equal to group dragged from
                return (container != null) && IsGroup(item);
            }

            return false;
        }

        private bool IsGroup(TreeViewItem container)
        {
            try
            {
                Group group = (Group)container.Header;
                return true;
            }
            catch
            {
                return false;
            }

        }
        

        private void GroupTreeView_DragLeave(object sender, DragEventArgs e)
        {
            TreeViewItem container;
            if (!IsValidDropTarget(e.OriginalSource as UIElement, out container))
            {
                e.Effects = DragDropEffects.None;
            }
            else
            {
                container.Background = new SolidColorBrush(Colors.White);
            }
            e.Handled = true;
            

        }

        #endregion


    }
}
